/**
 * 
 */
package cn.ac.istic.lkt.atv;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.imageio.ImageIO;


/**
 * @author scd
 *
 */
public class Convert2Image {
	int totallen = 0;
	int threadno = 1;
	public String mode = null;
	
	public class ConvertThread extends Thread{
		Convert2Image app = null;
		List<String> linesf = null;
		List<String> linese = null;
		List<String> linesa = null;
		int start=0, end=0;
		String dir = null;
		String prefix = null;
		public ConvertThread(Convert2Image app, List<String> lsf,List<String> lse,List<String> lsa,int a, int b,String d, String p){
			this.app = app;
			linesf = lsf;
			linese = lse;
			linesa = lsa;
			start=a;
			end=b;
			dir = d;
			prefix=p;
		}
		
		public void run(){
			System.out.println("thead "+start+" "+end+" started.");
			
			if (app.mode.equals("S")){
				TreePanelSingle tp = new TreePanelSingle();
				ParseTree pt1;
				for (int i=start; i<end; i++){
					pt1 = new ParseTree(linesf.get(i));
					tp.init(pt1);
					int numnum= (""+i).length();
					StringBuffer sb = new StringBuffer();
					for (int j =0; j < (totallen-numnum); j++){
						sb.append("0");
					}
					sb.append(""+i);			

					BufferedImage bi = tp.paintImage();
					try {			    
					    File outputfile = new File(dir+"/"+prefix+sb+".png");
					    ImageIO.write(bi, "png", outputfile);
					} catch (IOException e) {
					    e.printStackTrace();
					}
				}
			}
			else if (app.mode.equals("D")){			
				TreePanel2Tree tp = new TreePanel2Tree();
				ParseTree pt1,pt2;
				for (int i=start; i<end; i++){
					//System.out.println(i);
					pt1 = new ParseTree(linesf.get(i));
					pt2 = new ParseTree(linese.get(i));
					String linea = null;

//###error the following line
					tp.init(pt1,pt2,linesa.get(i),"ef");
					if(linesa != null){
						linea=linesa.get(i);
						tp.buildAlign(linea);
					}
					int numnum= (""+i).length();
					StringBuffer sb = new StringBuffer();
					for (int j =0; j < (totallen-numnum); j++){
						sb.append("0");
					}
					sb.append(""+i);			

					BufferedImage bi = tp.paintImage();
					try {			    
					    File outputfile = new File(dir+"/"+prefix+sb+".png");
					    ImageIO.write(bi, "png", outputfile);
					} catch (IOException e) {
					    e.printStackTrace();
					}

				}
			}
			else if (app.mode.equals("T2S")){
				TreePanel2String tp = new TreePanel2String();
				ParseTree pt ;
				for (int i=start; i<end; i++){
					//System.out.println(i);
					
					String sentence = linese.get(i);
					String a = linesa.get(i);
					//System.out.println(sentence);
					//System.out.println(a);

					pt = new ParseTree(linesf.get(i));
					tp.init(pt, sentence, a, "fe");
					
					String linea = null;

					int numnum= (""+i).length();
					StringBuffer sb = new StringBuffer();
					for (int j =0; j < (totallen-numnum); j++){
						sb.append("0");
					}
					sb.append(""+i);			

					BufferedImage bi = tp.paintImage();
					try {			    
					    File outputfile = new File(dir+"/"+prefix+sb+".png");
					    ImageIO.write(bi, "png", outputfile);
					} catch (IOException e) {
					    e.printStackTrace();
					}

				}
			}
			else{
				System.err.print("Unrecognized mode.");
			}
		}
	}

	public Convert2Image(String[] args){
		//String workd = System.getProperty("user.dir");
		
		Properties myConfig = new Properties();
		try{
		myConfig.load(new FileInputStream(args[0]));
		}catch(Exception e){
			e.printStackTrace();
			return;
		}
		
		// thread number
		String sthreadno = myConfig.getProperty("threadno").trim();
		System.out.println(sthreadno);
		if(sthreadno == null || sthreadno.equals("")){
			System.err.println("Thread number set incorrect, use default 1.");
			threadno = 1;
		}
		else{
			threadno = Integer.parseInt(sthreadno);		
			if(threadno<=0){
				System.err.println("Thread number set incorrect, use default 1.");
				threadno = 1;
			}
		}
		
		//mode single tree or double tree
		mode = myConfig.getProperty("mode").trim();		
		if (!(mode.equals("S")|| mode.equals("D") || mode.equals("T2S"))){
			System.err.println("Tree mode error, must use S or D");
			System.exit(-1);
		}
		
		//out-put dir
		String odir = myConfig.getProperty("odir").trim();
		if (odir == null || odir.equals("")){
			System.err.println("Error! please specify the output dir.");
		}
		if (! new File(odir).isDirectory()){
			System.err.println("Not a directory: "+odir);
			System.exit(-1);
		}
		
		//prefix
		String prefix = myConfig.getProperty("prefix").trim();
		if (prefix == null || prefix.equals("")){
			System.err.println("Error! please specify the image prefix.");
		}
		

		
		//file in
		String ffile = myConfig.getProperty("ffile").trim();
		File ff = new File(ffile);
		List<String> linesf = null;
		if (ff==null || !ff.canRead()) {
			System.err.println("Can't read file: "+ffile);
			System.exit(-1);
		}
		else{
			linesf = readFile(ff);
		}
		
		File fe = null;
		File fa = null;
		List<String> linese = null;
		List<String> linesa = null;
		if (mode.equals("D")||mode.equals("T2S")){
			String efile = myConfig.getProperty("efile").trim();
			if(efile==null || efile.equals("")){
				System.err.println("Need to specify another tree file for mode D ");
				System.exit(-1);
			}
			fe = new File(efile);
			if (fe==null || !fe.canRead()) {
				System.err.println("Can't read file: "+efile);
				System.exit(-1);
			}
			else{
				linese = readFile(fe);
			}
			
			String afile = myConfig.getProperty("afile").trim();
			if(! (afile==null) && !afile.equals("")){			
				fa = new File(afile);
				if (fa==null || !fa.canRead()) {
					System.err.println("Can't read file: "+afile);
					linesa = null;
				}
				else{
					linesa = readFile(fa);					
				}
			}
		}
		
		//output tree number
		String sonum = myConfig.getProperty("onum").trim();
		int onum ;
		if (prefix == null || prefix.equals("")){
			onum = linesf.size();
		}
		else onum = Integer.parseInt(sonum);
		
		int total= onum;
		totallen=(""+total).length();
		int part = total/threadno+1;
		//System.out.println(totallen);
		int s=0,e=part;
		
		//ConvertThread ct = new ConvertThread(ptlist,s,e,args[1],args[2]);
		//ct.start();
		while (true){		
			ConvertThread ct1 = new ConvertThread(this,linesf,linese,linesa,s,e,odir,prefix);
			ct1.start();

			s=e;
			e=s+part;
			if(e>total){
				e=total;
			}
			if(s>=total){
				break;
			}
		}
	}
	
	public List<String> readFile(File f){
		InputStream in = null;
		List<String> lines = new ArrayList<String>();
		try {
			in = new FileInputStream(f);
		    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		    String line = null;
		    while ((line = reader.readLine()) != null) {
		    	if(line.trim().length()==0){
		    		continue;
		    	}
		        lines.add(line.trim());
		    }
		    return lines;
		} catch (IOException x) {
		    System.err.println(x);		   
		    return null;
		} 
	}
	
	public void printConfigTemp(){
		System.err.println("usage: java cn.ac.istic.lkt.atv.Convert2Image " +
				"4(thread num) " +
				"D/S(tree mode) " +
				"output-directory " +
				"output-prefix " +
				"input-file-name  ");

	}
	/**
	 * @param args
	 * 0 : thread
	 * 1 : mode
	 * 2 : out-dir
	 * 3 : out-prefix
	 * 4 : in-f
	 * 5 : in-e
	 * 6 : in-a
	 */
	public static void main(String[] args) {
		//System.err.println(args.length);
		if(args.length < 1){
			System.err.println("Error: please specify the config file.");
			System.err.println("usage: java -mx1g cn.ac.istic.lkt.atv.Convert2Image config-file ");
			System.exit(-1);
		}
		// TODO Auto-generated method stub
		
		new Convert2Image(args);

	}

}
